/*
 * G2P_SyllableTree.cpp
 *
 *  Created on: Nov 19, 2012
 *      Author: Pongsathon Janyoi
 */
#include "g2p_syllable_tree.h"
#include "g2p_ngram.h"
#include "g2p_tone_gram.h"

syllable_stack * syllable_stack_create() {
	syllable_node ** syllable_nodes = (syllable_node **) calloc(200,
			sizeof(syllable_node *));
	syllable_stack * new_stack = (syllable_stack *) malloc(
			sizeof(syllable_stack));
	new_stack->element = syllable_nodes;
	new_stack->size = 0;
	new_stack->sum_len = 0;
	return new_stack;
}
void syllable_stack_push(syllable_stack * stack, syllable_node * node) {
	if (stack != NULL) {
		stack->element[stack->size++] = node;
		if (node->path_len > stack->sum_len) {
			stack->sum_len = node->path_len;
			//printf("\npath = %d", stack->sum_len);
		}
	}
	//syllable_stack[stack_len]= node;
	//stack_len++;
}
void syllable_stack_clear(syllable_stack * stack) {
	//printf("\nclear stack.");
	if (stack != NULL) {
		if (stack->element != NULL) {
			for (int i = 0; i < stack->size; i++) {
				syllable_node * node = stack->element[i];
				//printf("\nst %d %s %d", i, stack->element[i]->text,
				//		stack->element[i]->path_len);
				if (node != NULL) {
					if (node->text != NULL) {
						//printf("\nt %d %s", i, stack->element[i]->text);
						free(stack->element[i]->text);
						stack->element[i]->text = NULL;
						//printf("\nt %d %s",i,stack->element[i]->text);
					}
					/*
					 if (node->prob_tab_row > 0) {
					 for (int k = 0; k < node->prob_tab_row; k++) {
					 printf("free prob %p %d", node->prob_tab[k], k);
					 free(node->prob_tab[k]);
					 }
					 }*/
					/*if (node->child != NULL) {
					 free(node->child);
					 node->child = NULL;
					 }
					 if (node->parent != NULL) {
					 free(node->parent );
					 node->parent  = NULL;
					 }*/
					free(node);

				}

			}
			free(stack->element);
		}
		free(stack);
	}
}
syllable_node * syllable_stack_find(syllable_stack * stack, int len) {
	int i = 0;
	if (stack != NULL) {
		for (i = 0; i < stack->size; i++) {
			if (stack->element[i] != NULL) {
				if (len == stack->element[i]->path_len) {

					//printf("found [%d %s] Copy Tree.", i,
					//		stack->element[i]->text);
					return stack->element[i];

				}

			}
		}
	}
	return NULL;

}

void syllable_stack_print(syllable_stack * stack) {
	for (int i = 0; i < stack->size; i++) {
		printf("\n%s \t%d\t%d \t%p", stack->element[i]->text,
				stack->element[i]->path_len, stack->element[i]->child_size,
				stack->element[i]);
	}
}
syllable_node * syllable_tree_create_node(char * text) {
	syllable_node * new_node = (syllable_node *) malloc(sizeof(syllable_node));
	new_node->root = false;
	//new_node->child = (syllable_node **)calloc(30,sizeof(syllable_node*));
	//new_node->parent = (syllable_node **)calloc(30,sizeof(syllable_node*));;

	new_node->cal_prob = false;
	new_node->child_size = 0;
	new_node->path_len = 0;
	new_node->child_size = 0;
	new_node->parent_size = 0;
	new_node->prob_tab_max = 0;
	new_node->prob_tab_row = 0;
	//new_node->prob_tab = NULL;
	new_node->tone_mk = 0;
	new_node->traversal = false;
	if (text != NULL) {
		new_node->text = (char *) calloc(strlen(text) + 1, sizeof(char));
		strcpy(new_node->text, text);
	}
	return new_node;
}
syllable_node * syllable_tree_add_parent(syllable_node * parent,
		syllable_node * new_node) {
	if (parent == NULL)
		return NULL;

	//free(tmp_parent); //free old child
	new_node->parent[new_node->parent_size] = parent; //add new node
	new_node->parent_size++;

	return new_node;
}
syllable_node * syllable_tree_add_child(syllable_node * parent,
		syllable_node * new_node) {
	if (parent == NULL)
		return NULL;

	//free(tmp_child); //free old child
	parent->child[parent->child_size] = new_node; //add new node
	syllable_tree_add_parent(parent, new_node);
	parent->child_size++;

	return new_node;
}
syllable_node * syllable_tree_remove_child(syllable_node * parent,
		syllable_node * new_node) {

}
void * syllable_tree_print(syllable_node * node, char ** out_text, int level,
		int * max_level, int parent_id) {
	//printf("%s  ", node->text);

	*max_level = level;
	if (out_text[level] != NULL)
		strcat(out_text[level], " | ");
	for (int i = 0; i < node->child_size; i++) {
		if (out_text[level] == NULL) {
			out_text[level] = (char *) calloc(MAX_LINE_LEN, sizeof(char));
			char tmp[50] = "";

			sprintf(tmp, "%d", node->parent);
			strcat(out_text[level], tmp);
			strcat(out_text[level], ".");
			strcat(out_text[level], node->child[i]->text);
		} else {
			char tmp[50] = "";
			sprintf(tmp, "%d", node->parent);
			strcat(out_text[level], "  ");
			strcat(out_text[level], tmp);
			strcat(out_text[level], ".");
			strcat(out_text[level], node->child[i]->text);
		}
		syllable_tree_print(node->child[i], out_text, level + 1, max_level,
				parent_id);
	}
}
void * syllable_tree_print_result(char ** out_text, int max) {
	for (int i = 0; i < max; i++) {
		printf("%s\n", out_text[i]);
	}
}
syllable_prob_bundle * syllable_create_prob_bundle(int max_size) {
	syllable_prob_bundle * tmp = (syllable_prob_bundle *) malloc(
			sizeof(syllable_prob_bundle));
	//tmp->prob_chain = (syllable_prob_table **) calloc(max_size,
	//		sizeof(syllable_prob_table *));
	tmp->size = 0;
	tmp->max_size = max_size;
	return tmp;
}
void syllable_free_prob_bundle(syllable_prob_bundle * bundle) {
	if (bundle != NULL) {
		if (bundle->prob_chain != NULL) {
			free(bundle->prob_chain);
		}
		free(bundle);
	}
}
syllable_prob_bundle * syllable_clone_prob_bundle(syllable_prob_bundle * b1) {
	if (b1 == NULL)
		return NULL;

	syllable_prob_bundle * tmp = syllable_create_prob_bundle(b1->max_size);
	for (int i = 0; i < b1->size; i++) {
		tmp->prob_chain[i] = b1->prob_chain[i];
	}
	tmp->prob = b1->prob;
	tmp->size = b1->size;
	return tmp;
}
void syllable_prob_bundle2phoneme(syllable_prob_bundle * b1, char * out_phone) {
	if (b1 != NULL) {
		//printf("\nP:%.4f", b1->prob);
		char phoneme[500] = "";
		char phonetic[500] = "";
		strcat(phoneme, "");
		char pne[100] = "";
		char pnt[100] = "";
		for (int i = b1->size - 1; i >= 0; i--) {
			syllable_node * node = b1->prob_chain[i]->child;
			pronun_struct_unit * st =
					b1->prob_chain[i]->child->struc->st[b1->prob_chain[i]->cst_id];

			tone_ConsonantToneMarker(node->text, node->text_len, st);
			tone_syllable_sound_type(st);
			char tmp_p1[50] = "";
			int tone1 = tone_soundTone(st, 1);
			pronun_sturct_num2phone(tmp_p1, st->st1, 0);
			//pronun_sturct_num2phonetic(mpnt, st->st1, tone1);
			sprintf(pne, "%s-%d|", tmp_p1, tone1);
			strcat(phoneme, pne);
			/*for 2 sound*/
			if (st->sound == 2) {
				char tmp_pne[50] = "";
				char tmp_p2[50] = "";
				int tone2 = tone_soundTone(st, 2);
				pronun_sturct_num2phone(tmp_p2, st->st2, 0);
				sprintf(tmp_pne, "%s-%d|", tmp_p2, tone2);
				strcat(phoneme, tmp_pne);
			}

		}
		if (out_phone != NULL)
			strcpy(out_phone, phoneme);

		//printf("\n\t%s\n\t%s", phoneme, phonetic);
	} else {
		//printf("\ntab_max = null");
	}

}
void syllable_prob_bundle2sylseq(syllable_prob_bundle * b1, syllable_seq * seq,
		int wnum) {
	if (b1 != NULL) {
		int code_count = 0;
		char wseg[1024] = "";
		for (int i = b1->size - 1; i >= 0; i--) {

			syllable_node * node = b1->prob_chain[i]->child;
			strcat(wseg, "|");
			strcat(wseg, node->text);
			pronun_struct_unit * st =
					b1->prob_chain[i]->child->struc->st[b1->prob_chain[i]->cst_id];

			tone_ConsonantToneMarker(node->text, node->text_len, st);
			tone_syllable_sound_type(st);

			syllable_seq_unit * unit = (syllable_seq_unit *) malloc(
					sizeof(syllable_seq_unit));

			unit->c = st->c1;
			unit->mt = st->t1;
			unit->wt = st->wt1;
			unit->sylcode = st->st1;
			unit->tone = -1;
			unit->wdnum = wnum;
			unit->src = 'P';
			syllable_seq_add(seq, unit);

			if (st->sound == 2) {
				syllable_seq_unit * unit = (syllable_seq_unit *) malloc(
						sizeof(syllable_seq_unit));
				unit->c = st->c2;
				unit->mt = st->t2;
				unit->sylcode = st->st2;
				unit->wt = st->wt2;
				unit->tone = -1;
				unit->wdnum = i;
				syllable_seq_add(seq, unit);
			}
		}
		strcat(wseg, "|");
		strcat(seq->wseg, wseg);
	}
}
void syllable_prob_sylseq_predict_tone(syllable_seq * seq) {
	tone_node * tnodes = tone_ngram_create_node();
	tnodes->r = true;
	tone_node * tcurr = tnodes;
	//tone_ngram_free_node(tnodes); //free tnode;
	//	return ;
	//select tone sound all syllable
	for (int i = 0; i < seq->size; i++) {
		syllable_seq_unit * unit = seq->seq[i];
		char code_phone[512];
		sprintf(code_phone, "%d%d%06d", unit->mt, unit->c, unit->sylcode);
		/*test*/
		tone_node * tnode = tone_ngram_create_node();
					tnode->syl = unit;
		if (unit->tone != -1) { //dict tone not found
			tnode->p_tone[0] = unit->tone;
		} else {
			int ptone = tone_ngram_pattern_seach(code_phone);
			//printf("\n%s\t%d", code_phone, ptone);
			/*find prob */

			if (ptone != -1) {
				int tone_sound = 0;
				int d_tone;
				int tmp_ptone = ptone;
				while (tmp_ptone != 8) {
					char tmp_pattern[100] = "";
					d_tone = tmp_ptone % 10;
					sprintf(tmp_pattern, "%d%s", d_tone, code_phone);
					//printf("\nSreach Prob Pattern : %s", tmp_pattern);
					float p = tone_ngram_seach(tmp_pattern);
					//printf("/t%.4f",p);
					tnode->p_tone[tnode->tone_count++] = d_tone;
					//printf("\n%d", d_tone);
					tmp_ptone = tmp_ptone / 10;
					tone_sound++;
				}

			}
		}
		tnode->parent = tcurr;
		tcurr->child = tnode;
		tcurr = tnode;
	}

	//precess prob
	//printf("\nProcess Tone prob.");
	tcurr = tnodes->child;
	int c = 0;
	while (tcurr != NULL) {
		//printf("==>\n%p\t%d\n", tcurr, tcurr->tone_count);
		tone_node * pr = tcurr->parent;
		tone_node * ch = tcurr->child;
		/*last syl */
		if (ch == NULL) {
			for (int m = 0; m < tcurr->tone_count; m++) { //current syl
				//printf("\n==>cccc");
				char current_code[32] = "";
				sprintf(current_code, "%d%d%d%06d", tcurr->p_tone[m],
						tcurr->syl->mt, tcurr->syl->c, tcurr->syl->sylcode);
				for (int l = 0; l < pr->tone_count; l++) { //parent syl
					char parent_code[32] = "";

					sprintf(parent_code, "%d%d%d%06d", pr->p_tone[l],
							pr->syl->mt, pr->syl->c, pr->syl->sylcode);
					float p1 = tone_ngram_calculate(parent_code, current_code);
					//printf("\n%f.", p1);
					tcurr->mem_tone[tcurr->tone_prob_size] = tcurr->p_tone[m];
					tcurr->mem_prob[tcurr->tone_prob_size++] = p1; //previous + next

					if (p1 > tcurr->max_prob) { //change max
						tcurr->max_prob = p1;
						tcurr->select_tone = tcurr->p_tone[m];
						seq->seq[c]->tone = tcurr->p_tone[m]; //update tone of sequence
					}
				}
			}

			//break;
		} else if (pr->r) {

			for (int m = 0; m < tcurr->tone_count; m++) { //current syl
				char current_code[32] = "";
				sprintf(current_code, "%d%d%d%06d", tcurr->p_tone[m],
						tcurr->syl->mt, tcurr->syl->c, tcurr->syl->sylcode);
				if (ch->tone_count > 0) {
					for (int n = 0; n < ch->tone_count; n++) {
						char child_code[32] = "";
						sprintf(child_code, "%d%d%d%06d", ch->p_tone[n],
								ch->syl->mt, ch->syl->c, ch->syl->sylcode);

						float p1 = tone_ngram_calculate(current_code,
								child_code);

						tcurr->mem_tone[tcurr->tone_prob_size] =
								tcurr->p_tone[m];
						tcurr->mem_prob[tcurr->tone_prob_size++] = p1; //previous + next

						if (p1 > tcurr->max_prob) { //change max
							tcurr->max_prob = p1;
							tcurr->select_tone = tcurr->p_tone[m];
							seq->seq[c]->tone = tcurr->p_tone[m]; //update tone of sequence
						}
					} //end n
				} else {
					float p1 = tone_ngram_calculate(current_code, "");
					tcurr->mem_tone[tcurr->tone_prob_size] = tcurr->p_tone[m];
					tcurr->mem_prob[tcurr->tone_prob_size++] = p1; //previous + next

					if (p1 > tcurr->max_prob) { //change max
						tcurr->max_prob = p1;
						tcurr->select_tone = tcurr->p_tone[m];
						seq->seq[c]->tone = tcurr->p_tone[m]; //update tone of sequence
					}
				}
			}

		} else {
			/*inner syl*/
			if (tcurr->tone_count > 0 && pr->tone_count > 0 && ch->tone_count) {
				for (int m = 0; m < tcurr->tone_count; m++) { //current syl
					char current_code[32] = "";
					sprintf(current_code, "%d%d%d%06d", tcurr->p_tone[m],
							tcurr->syl->mt, tcurr->syl->c, tcurr->syl->sylcode);

					for (int l = 0; l < pr->tone_count; l++) { //parent syl
						char parent_code[32] = "";

						sprintf(parent_code, "%d%d%d%06d", pr->p_tone[l],
								pr->syl->mt, pr->syl->c, pr->syl->sylcode);

						for (int n = 0; n < ch->tone_count; n++) {
							char child_code[32] = "";
							sprintf(child_code, "%d%d%d%06d", ch->p_tone[n],
									ch->syl->mt, ch->syl->c, ch->syl->sylcode);
							//printf("%s  %s", parent_code, current_code);
							float p1 = tone_ngram_calculate(parent_code,
									current_code);
							float p2 = tone_ngram_calculate(current_code,
									child_code);

							//printf("\nP = %.4f + %.4f = %.4f", p1, p2, p1 + p2);

							tcurr->mem_tone[tcurr->tone_prob_size] =
									tcurr->p_tone[m];
							tcurr->mem_prob[tcurr->tone_prob_size++] = p1 + p2; //previous + next

							if (p1 + p2 > tcurr->max_prob) { //change max
								tcurr->max_prob = p1 + p2;
								tcurr->select_tone = tcurr->p_tone[m];
								seq->seq[c]->tone = tcurr->p_tone[m]; //update tone of sequence
							}

						} //end n

					} //end m
				} //end l
			} else if (tcurr->tone_count > 0 && pr->tone_count > 0) {
				for (int m = 0; m < tcurr->tone_count; m++) { //current syl
					char current_code[32] = "";
					sprintf(current_code, "%d%d%d%06d", tcurr->p_tone[m],
							tcurr->syl->mt, tcurr->syl->c, tcurr->syl->sylcode);
					for (int l = 0; l < pr->tone_count; l++) { //parent syl
						char parent_code[32] = "";

						sprintf(parent_code, "%d%d%d%06d", pr->p_tone[l],
								pr->syl->mt, pr->syl->c, pr->syl->sylcode);
						float p1 = tone_ngram_calculate(parent_code,
								current_code);
						printf("\n%f.", p1);
						tcurr->mem_tone[tcurr->tone_prob_size] =
								tcurr->p_tone[m];
						tcurr->mem_prob[tcurr->tone_prob_size++] = p1; //previous + next

						if (p1 > tcurr->max_prob) { //change max
							tcurr->max_prob = p1;
							tcurr->select_tone = tcurr->p_tone[m];
							seq->seq[c]->tone = tcurr->p_tone[m]; //update tone of sequence
						}
					}
				}
			} else if (tcurr->tone_count > 0 && ch->tone_count) {
				for (int m = 0; m < tcurr->tone_count; m++) { //current syl
					char current_code[32] = "";
					sprintf(current_code, "%d%d%d%06d", tcurr->p_tone[m],
							tcurr->syl->mt, tcurr->syl->c, tcurr->syl->sylcode);
					if (ch->tone_count > 0) {
						for (int n = 0; n < ch->tone_count; n++) {
							char child_code[32] = "";
							sprintf(child_code, "%d%d%d%06d", ch->p_tone[n],
									ch->syl->mt, ch->syl->c, ch->syl->sylcode);

							float p1 = tone_ngram_calculate(current_code,
									child_code);

							tcurr->mem_tone[tcurr->tone_prob_size] =
									tcurr->p_tone[m];
							tcurr->mem_prob[tcurr->tone_prob_size++] = p1; //previous + next

							if (p1 > tcurr->max_prob) { //change max
								tcurr->max_prob = p1;
								tcurr->select_tone = tcurr->p_tone[m];
								seq->seq[c]->tone = tcurr->p_tone[m]; //update tone of sequence
							}
						} //end n
					}
				}
			} else {
				for (int m = 0; m < tcurr->tone_count; m++) { //current syl
					char current_code[32] = "";
					sprintf(current_code, "%d%d%d%06d", tcurr->p_tone[m],
							tcurr->syl->mt, tcurr->syl->c, tcurr->syl->sylcode);

					float p1 = tone_ngram_calculate(current_code, "");
					tcurr->mem_tone[tcurr->tone_prob_size] = tcurr->p_tone[m];
					tcurr->mem_prob[tcurr->tone_prob_size++] = p1; //previous + next

					if (p1 > tcurr->max_prob) { //change max
						tcurr->max_prob = p1;
						tcurr->select_tone = tcurr->p_tone[m];
						seq->seq[c]->tone = tcurr->p_tone[m]; //update tone of sequence
					}

				}
			}
		}
		//printf("\nc = %d", c);
		if (seq->seq[c]->tone == -1) {
			pronun_struct_unit st;
			st.c1 = tcurr->syl->c;
			st.st1 = tcurr->syl->sylcode;
			st.wt1 = tcurr->syl->wt;
			st.t1 = tcurr->syl->mt;
			int tone = tone_soundTone(&st, 1);
			seq->seq[c]->tone = tone;
		}
		tcurr = tcurr->child;
		c++;
	}

	tone_ngram_free_node(tnodes); //free tnode;

}

void syllable_prob_bundle2phoneme_code(syllable_prob_bundle * b1,
		char * out_phone) {
	if (b1 != NULL) {
		char symbol_tone[100][20] = { "M", "L", "MF", "HF", "H", "R" };
		//printf("\nP:%.4f", b1->prob);
		char phoneme[500] = "";
		char phonetic[500] = "";

		char phoneme_code[500] = "";
		strcat(phoneme, "");
		char pne[100] = "";
		char pnt[100] = "";
		char pne_c[100] = "";

		for (int i = b1->size - 1; i >= 0; i--) {
			syllable_node * node = b1->prob_chain[i]->child;
			pronun_struct_unit * st =
					b1->prob_chain[i]->child->struc->st[b1->prob_chain[i]->cst_id];

			tone_ConsonantToneMarker(node->text, node->text_len, st);
			tone_syllable_sound_type(st);
			char tmp_p1[50] = "";
			int tone1 = tone_soundTone(st, 1);
			pronun_sturct_num2phone(tmp_p1, st->st1, 0);
			//pronun_sturct_num2phonetic(mpnt, st->st1, tone1);
			sprintf(pne, "%s-%d-%d-%s|", symbol_tone[tone1], st->t1, st->c1,
					tmp_p1);
			sprintf(pne_c, "%d%s%d%06d", st->t1, symbol_tone[tone1], st->c1,
					st->st1);
			strcat(phoneme, pne);
			strcat(phoneme_code, pne_c);
			/*for 2 sound*/
			if (st->sound == 2) {
				char tmp_pne[50] = "";
				char tmp_pne_c[50] = "";
				char tmp_p2[50] = "";
				int tone2 = tone_soundTone(st, 2);
				pronun_sturct_num2phone(tmp_p2, st->st2, 0);
				sprintf(tmp_pne, "%s-%d-%d-%s|", symbol_tone[tone2], st->t2,
						st->c2, tmp_p2);
				sprintf(tmp_pne, "%d%s%d%6d|", st->t2, symbol_tone[tone2],
						st->c2, st->st2);
				strcat(phoneme, tmp_pne);
				strcat(phoneme_code, tmp_pne);
			}

		}
		sprintf(out_phone, "%s", phoneme);

		//printf("\n\t%s\n\t%s", phoneme, phonetic);
	} else {
		//printf("\ntab_max = null");
	}

}

void syllable_prob_bundle_print(syllable_prob_bundle * b1, _IO_FILE * t) {

	if (b1 != NULL) {
		printf("\nP:%.4f", b1->prob);
		char phoneme[500] = "";
		char phonetic[500] = "";
		strcat(phoneme, "|");
		char * mtmp = (char *) calloc(100, sizeof(char));
		char * mpnt = (char *) calloc(100, sizeof(char));
		for (int i = b1->size - 1; i >= 0; i--) {

			syllable_node * node = b1->prob_chain[i]->child;
			pronun_struct_unit * st =
					b1->prob_chain[i]->child->struc->st[b1->prob_chain[i]->cst_id];

			tone_ConsonantToneMarker(node->text, node->text_len, st);
			tone_syllable_sound_type(st);
			int tone = 0;	//tone_soundTone(st);
			pronun_sturct_num2phone(mtmp, st->st1, 0);
			pronun_sturct_num2phonetic(mpnt, st->st1, tone);
			int c1 = st->c1;
			char gc[500] = "";
			sprintf(gc, "(t=%d m=%d c=%d Tone = %d)", st->wt1, st->t1, c1,
					tone);
			strcat(phonetic, "[");
			strcat(phoneme, gc);
			strcat(phoneme, mtmp);
			strcat(phonetic, mpnt);
			strcat(phoneme, "|");
			strcat(phonetic, "]");

		}
		//printf("\n\t%s\n\t%s", phoneme, phonetic);
		free(mtmp);
		free(mpnt);
	} else {
		//printf("\ntab_max = null");
	}
}
void syllable_prob_maximum_print(syllable_maximum_pair * pair) {
	if (pair != NULL) {
		printf("\nP:%.4f", pair->prob);
		char phoneme[1024] = "";
		char phonetic[1024] = "";
		strcat(phoneme, "|");
		char * mtmp = (char *) calloc(20, sizeof(char));
		char * mpnt = (char *) calloc(20, sizeof(char));
		for (int i = pair->size - 1; i >= 0; i--) {

			//syllable_node * node =  b1->prob_chain[i]->child;
			pronun_struct_unit * st = pair->unit[i];
			if (st == NULL)
				continue;
			//printf("\n# %d",st->c1);
			tone_syllable_sound_type(st);
			int tone = 0;	//tone_soundTone(st);
			//printf("\nst->st1 = %06d", st->st1);
			int st1 = st->st1;
			pronun_sturct_num2phone(mtmp, st1, 0);
			pronun_sturct_num2phonetic(mpnt, st->st1, tone);
			int c1 = st->c1;
			char gc[500] = "";
			sprintf(gc, "(t=%d m=%d c=%d Tone = %d)", st->wt1, st->t1, c1,
					tone);
			strcat(phonetic, "[");
			strcat(phoneme, gc);
			strcat(phoneme, mtmp);
			strcat(phonetic, mpnt);
			strcat(phoneme, "|");
			strcat(phonetic, "]");

		}
		//printf("\n\t%s\n\t%s", phoneme, phonetic);
		free(mtmp);
		free(mpnt);
	} else {
		//printf("\ntab_max = null");
	}
}
syllable_prob_table ** syllable_create_prob_table(syllable_node * node,
		int max_size) {
	syllable_prob_table ** table = NULL;
	if (node != NULL) {
		table = (syllable_prob_table **) calloc(max_size,
				sizeof(syllable_prob_table *));
		node->prob_tab_max = max_size;
		node->prob_tab_row = 0;
	}
	return table;
}
syllable_stack_tab * syllable_create_stack_prob_table(int max_size) {
	syllable_stack_tab * stack = (syllable_stack_tab*) malloc(
			sizeof(syllable_stack_tab));
	stack->size = 0;

	return stack;
}
void syllable_print_stack_prob_table(syllable_stack_tab * stack) {
	if (stack != NULL) {
		for (int i = 0; i < stack->size; i++) {
			printf("\n%p ", stack->element[i]);
		}
	}
}
void syllable_free_stack_prob_table(syllable_stack_tab * stack) {
	if (stack != NULL) {
		//printf("prob table stack = %d",stack->size);
		for (int i = 0; i < stack->size; i++) {
			syllable_prob_table * tab = stack->element[i];
			//printf("\ntable %d %p",i,tab);
			free(tab);
			//if (tab != NULL)
			//	free(tab);
		}

		free(stack);
	}
}

/*======== sylable sequence =========*/
syllable_seq_unit * syllable_seq_unit_create() {
	syllable_seq_unit * unit = (syllable_seq_unit *) malloc(
			sizeof(syllable_seq_unit));
	unit->c = 0;
	unit->mt = 0;
	unit->sylcode = 0;
	unit->tone = 0;
	unit->wt = 0;
	unit->wdnum = 0;
	return unit;
}

syllable_seq * syllable_seq_create(int max_size) {
	syllable_seq * seq = (syllable_seq *) malloc(sizeof(syllable_seq));
	seq->mex_size = max_size;
	seq->size = 0;
	strcpy(seq->wseg, "");
	seq->seq = (syllable_seq_unit **) calloc(max_size,
			sizeof(syllable_seq_unit *));
	return seq;
}
int syllable_seq_free(syllable_seq * seq) {
	if (seq == NULL)
		return -1;
	for (int i = 0; i < seq->size; i++) {
		free(seq->seq[i]);
	}

	free(seq->seq);
	free(seq);
	return 1;
}
void syllable_seq_add(syllable_seq * parent, syllable_seq_unit * node) {
	if (parent != NULL) {
		if (parent->size + 1 < parent->mex_size)
			parent->seq[parent->size++] = node;
	}
}
void syllable_seq_cat(syllable_seq * s1, syllable_seq * s2) {
	if (s1 != NULL) {
		for (int i = 0; i < s2->size; i++) {
			syllable_seq_add(s1, s2->seq[i]);
		}
		free(s2->seq);
		free(s2);
	}
}
void syllable_seq_print(syllable_seq * s) {
	if (s == NULL) {
		printf("\nSeq NULL");

	} else {
		printf("\nN\tCode\tCons\tTomk\t\Wt\tPredict Tone");
		for (int i = 0; i < s->size; i++) {
			syllable_seq_unit * u = s->seq[i];
			printf("\n%d\t%06d\t%d\t%d\t%d\t%d\t%d\t%c", u->wdnum, u->sylcode, u->c,
					u->mt, u->wt, u->wdnum, u->tone,u->src);
		}
		printf("\n-----------------------");
	}
}
